<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Index</title>
  </head>
  <body></body>
  <script type="text/javascript">
    // 原始类型 typeof 就是这个类型
    // 包装类型 typeof 结果是 object

    
    // 思考1：我们定义一个字符串是什么类型？
    const a = '12345'
    console.log(typeof a) // string

    // 原始数据类型是没有方法(函数), 那可以调用字符串函数吗
    const b = a.slice(1, 4)
    console.log(b) // 234
    console.log(typeof b) // string

    /* 
        答案是： ECMAScript 提供了三种特殊的引用类型 Boolean Number String。
        每当用到某个原始值的方法或属性时，后台都会创建一个相应原始包装类型的对象。
    */

    // 后台处理其实经过了如下的过程
    /* 
        const a = '12345'
        const c = new String(a)         // 创建一个 String 类型实例
        const b = c.slice(1, 4)         // 调用实例上的方法
        c = null                        // 销毁实例
    */

    // 思考2: 给原始值添加属性可以吗？也就是定义一个字符串，能给字符串添加属性吗？
    let s = 'zs'
    s.name = 'test'
    console.log(s.name) // undefined
    /* 
         s.name = 'test'     // 这行创建了一个 String 对象, 但是这行代码执行完 String 对象就销毁了
         console.log(s.name) // 这行代码同样创建了 String 对象, 但是这个 String 对象中并没有 name 属性
    */

    // 思考3：类型转换
    const n1 = 10
    console.log(typeof n1) // number
    const n2 = Number('10')
    console.log(typeof n2) // number
    console.log(n1 === n2) // true
    const n3 = new Number('10')
    console.log(typeof n3) // object

    const s1 = '123'
    const s2 = String(123)
    console.log(typeof s1) // string
    console.log(typeof s2) // string
    console.log(s1 === s2) // true

    const s3 = new String(123)
    console.log(typeof s3) // object
  </script>
</html>
